package com.block.match.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.block.common.constant.AppRspCodeConstant;
import com.block.common.constant.RedisKeyConstant;
import com.block.common.service.IApplicationInfoService;
import com.block.common.service.LogFactory;
import com.block.common.vo.ResponseVo;
import com.block.db.entity.*;
import com.block.db.mapper.ChannelBaseInfoMapper;
import com.block.db.mapper.DataMatchOrderItemMapper;
import com.block.db.mapper.MemberSourceInfoMapper;
import com.block.db.mapper.MerchantBaseInfoMapper;
import com.block.match.enums.OrderStatusEnum;
import com.block.match.model.vo.MatchResultVO;
import com.block.match.service.IDataMatchOrderInfoService;
import com.block.match.service.IDataMatchOrderItemService;
import com.block.match.service.IMatchApiBHandlerService;
import com.block.merchant.model.result.DataMatchResult;
import com.block.merchant.model.vo.MerchantAbiBDataPushInfoVO;
import com.block.merchant.service.IDataMerchantPushService;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Service
public class MatchApiBHandlerServiceImpl implements IMatchApiBHandlerService {

    private static final Logger log = LogFactory.getCommLog();

    @Resource
    MemberSourceInfoMapper memberSourceInfoMapper;
    @Autowired
    IDataMatchOrderInfoService dataMatchOrderInfoService;
    @Resource
    DataMatchOrderItemMapper dataMatchOrderItemMapper;
    @Autowired
    IDataMerchantPushService dataMerchantPushService;
    @Resource
    MerchantBaseInfoMapper merchantBaseInfoMapper;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    IDataMatchOrderItemService dataMatchOrderItemService;
    @Autowired
    ChannelBaseInfoMapper channelBaseInfoMapper;
    @Autowired
    IApplicationInfoService applicationInfoService;

    @Override
    @Async
    public void getApiBMatchResult(Long uid) {

        try {

            MemberSourceInfo memberSourceInfo = memberSourceInfoMapper.getEntityByUidLock(Long.valueOf(uid));
            if (ObjectUtil.isEmpty(memberSourceInfo)) {
                log.info("用户信息为空");
                return;
            }

            DataMatchOrderInfo dataMatchOrderInfo = dataMatchOrderInfoService.initMatchOrderInfo(memberSourceInfo);
            MatchResultVO matchResultVO = new MatchResultVO();
            matchResultVO.setOrderId(String.valueOf(dataMatchOrderInfo.getId()));

            // 条件过滤
            DataMatchResult dataMatchResult = dataMerchantPushService.dataMatchApiBHandle(memberSourceInfo);
            if (dataMatchResult.getMatchSize() == 0) {

                matchResultVO.setMatchSuccess(false);

                DataMatchOrderInfo updateOrder = new DataMatchOrderInfo();
                updateOrder.setId(dataMatchOrderInfo.getId());
                updateOrder.setStatus(OrderStatusEnum.FAILED.getValue());
                updateOrder.setMessage("没有匹配到合适的商户信息");
                dataMatchOrderInfoService.updateById(updateOrder);
                log.info("【客户信息匹配】匹配完成，没有匹配到合适的商户【orderId】{}", dataMatchOrderInfo.getId());
//            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "没有匹配到合适的商户信息",null);
                return;
            }

            dataMatchResult.setMatchOrderId(dataMatchOrderInfo.getId());
            dataMatchResult.setUid(memberSourceInfo.getUid());

            /**
             * 根据匹配结果，更新匹配订单信息
             */
            dataMatchOrderInfoService.saveMatchOrderResult(dataMatchResult, dataMatchOrderInfo, memberSourceInfo);

//        return new ResponseVo(AppRspCodeConstant.SUCCESS,"申请成功",null);
            return;
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    // 查询订单信息
    // orderItem
    @Override
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public ResponseVo getApiBApproveUrlListResult(Long uid, String channelCode) {
        JSONObject jsonObject = new JSONObject();
        MemberSourceInfo memberSourceInfo = memberSourceInfoMapper.getEntityByUidLock(Long.valueOf(uid));
        if (ObjectUtil.isEmpty(memberSourceInfo)) {
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "用户信息为空", jsonObject);
        }

        ArrayList<MerchantAbiBDataPushInfoVO> merchantAbiBDataPushInfoVOList = new ArrayList<>();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "操作被中断");
        }
        List<DataMatchOrderItem> itemListByUidAndWaitPush = dataMatchOrderItemMapper.getItemListByUidAndWaitPush(uid);
        if (itemListByUidAndWaitPush.size() == 0) {
            //return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "无商户匹配的子订单项",jsonObject);
            jsonObject.put("dataList", merchantAbiBDataPushInfoVOList);
            return new ResponseVo(AppRspCodeConstant.SUCCESS, "查询成功", jsonObject);
        }


//        ChannelBaseInfo channelBaseInfo = channelBaseInfoMapper.getBaseInfoByCode(channelCode);
//        if (StrUtil.equals(channelBaseInfo.getApibStatus().toString(), "0")) {
//            jsonObject.put("dataList", merchantAbiBDataPushInfoVOList);
//            return new ResponseVo(AppRspCodeConstant.SUCCESS, "此渠道不展示半流程", jsonObject);
//        }

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDateTime dateTime = LocalDateTime.now();
        String formattedDateTime = dateTime.format(formatter);
        String successNumberKey = StrUtil.format(RedisKeyConstant.MATCH_APIB_UIDS_LIST, formattedDateTime);

        // 先检查元素是否在 Redis List 中（保证唯一性）
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(successNumberKey))) {
            // 获取该 list 中的所有元素
            List<String> elements = stringRedisTemplate.opsForList().range(successNumberKey, 0, -1);

            // 如果元素不在 list 中，添加元素
            if (elements != null && !elements.contains(String.valueOf(uid))) {
                stringRedisTemplate.opsForList().rightPush(successNumberKey, String.valueOf(uid));
            }
        } else {
            // 如果该键不存在，创建 list 并添加元素
            stringRedisTemplate.opsForList().rightPush(successNumberKey, String.valueOf(uid));
            stringRedisTemplate.expire(successNumberKey, 7, TimeUnit.DAYS);
        }

        // 获取当前时间
        LocalDateTime currentTime = LocalDateTime.now();


        itemListByUidAndWaitPush.sort((p1, p2) -> p2.getProfitAmount().compareTo(p1.getProfitAmount()));
        //  找出所有单推机构（singlePushFlag=0）
        List<DataMatchOrderItem> singlePushItems = itemListByUidAndWaitPush.stream()
                .filter(item -> {
                    MerchantBaseInfo merchant = merchantBaseInfoMapper.selectById(item.getInfoId());
                    return merchant != null && merchant.getSinglePushFlag() != null
                            && merchant.getSinglePushFlag() == 0;
                })
                .collect(Collectors.toList());


        // 如果有单推机构，只返回第一个（最高利润的）单推机构
        List<DataMatchOrderItem> itemsToProcess = !singlePushItems.isEmpty()
                ? Collections.singletonList(singlePushItems.get(0))
                : itemListByUidAndWaitPush; // 没有单推机构则返回所有
        if (itemsToProcess.size() == 1) {
            DataMatchOrderItem dataMatchOrderItem = itemsToProcess.get(0);
            MerchantBaseInfo merchantBaseInfo = merchantBaseInfoMapper.selectById(dataMatchOrderItem.getInfoId());
            MerchantAbiBDataPushInfoVO merchantAbiBDataPushInfoVO = buildPushInfoVO(dataMatchOrderItem, merchantBaseInfo, memberSourceInfo, currentTime);
            if (merchantAbiBDataPushInfoVO == null ) {
                jsonObject.put("dataList",  merchantAbiBDataPushInfoVOList);
                return new ResponseVo(AppRspCodeConstant.SUCCESS, "查询成功", jsonObject);
            }
            merchantAbiBDataPushInfoVOList.add(merchantAbiBDataPushInfoVO);
            jsonObject.put("dataList",  merchantAbiBDataPushInfoVOList);
            return new ResponseVo(AppRspCodeConstant.SUCCESS, "查询成功", jsonObject);
        } else {
            for (DataMatchOrderItem matchOrderItem : itemListByUidAndWaitPush) {
                MerchantBaseInfo merchantBaseInfo = merchantBaseInfoMapper.selectById(matchOrderItem.getInfoId());
                MerchantAbiBDataPushInfoVO merchantAbiBDataPushInfoVO = buildPushInfoVO(matchOrderItem, merchantBaseInfo, memberSourceInfo, currentTime);
                if (merchantAbiBDataPushInfoVO == null ) {
                    jsonObject.put("dataList",  merchantAbiBDataPushInfoVOList);
                    return new ResponseVo(AppRspCodeConstant.SUCCESS, "查询成功", jsonObject);
                }
                merchantAbiBDataPushInfoVOList.add(merchantAbiBDataPushInfoVO);
            }

            jsonObject.put("dataList",  merchantAbiBDataPushInfoVOList);
            return new ResponseVo(AppRspCodeConstant.SUCCESS, "查询成功", jsonObject);
        }

//        List<MerchantAbiBDataPushInfoVO> merchantAbiBDataPushInfoVOList1 = itemsToProcess.stream()
//                .filter(item -> {
//                    Duration duration = Duration.between(item.getTimeoutPeriod(), currentTime);
//                    return Math.abs(duration.toMinutes()) <= 30;
//                })
//                .map(item -> {
//                    MerchantBaseInfo merchantBaseInfo = merchantBaseInfoMapper.selectById(item.getInfoId());
//                    MerchantAbiBDataPushInfoVO merchantAbiBDataPushInfoVO = buildPushInfoVO(item,merchantBaseInfo,memberSourceInfo);
//                    return merchantAbiBDataPushInfoVO;
//                })
//                .collect(Collectors.toList());
//
//        jsonObject.put("dataList", merchantAbiBDataPushInfoVOList1);
//        return new ResponseVo(AppRspCodeConstant.SUCCESS, "查询成功", jsonObject);
    }


    @Override
    public ResponseVo getApiBOrderItemClick(String orderItemId, String infoId) {
        DataMatchOrderItem entityByItemOrderIdAndInfoId = dataMatchOrderItemMapper.getEntityByItemOrderIdAndInfoId(Long.valueOf(orderItemId), Integer.valueOf(infoId));
        if (ObjectUtil.isEmpty(entityByItemOrderIdAndInfoId)) {
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "参数不正确");
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "操作被中断");
        }
        DataMatchOrderItem dataMatchOrderItem = new DataMatchOrderItem();
        dataMatchOrderItem.setId(Long.valueOf(orderItemId));
        dataMatchOrderItem.setClickPushFlag(1);
        int i = dataMatchOrderItemMapper.updateById(dataMatchOrderItem);
        if (i != 1) {
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "操作失败");
        }
        return new ResponseVo(AppRspCodeConstant.SUCCESS, "操作完成");
    }

    @Override
    public ResponseVo getAgainApiBOrderList(Long uid,String channelCode) {
        JSONObject jsonObject = new JSONObject();
        List<MerchantAbiBDataPushInfoVO> resultList = new ArrayList<>();
        LocalDateTime currentTime = LocalDateTime.now();
        MemberSourceInfo memberSourceInfo = memberSourceInfoMapper.getEntityByUidLock(Long.valueOf(uid));
        if (ObjectUtil.isEmpty(memberSourceInfo)) {
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "用户信息为空", jsonObject);
        }
//        ChannelBaseInfo channelBaseInfo = channelBaseInfoMapper.getBaseInfoByCode(channelCode);
//        if (StrUtil.equals(channelBaseInfo.getApibStatus().toString(), "0")) {
//            jsonObject.put("dataList", resultList);
//            return new ResponseVo(AppRspCodeConstant.SUCCESS, "此渠道不展示半流程", jsonObject);
//        }
        //List<MerchantAbiBDataPushInfoVO> merchantAbiBDataPushInfoVO = new ArrayList<>();
//        try {
//            Thread.sleep(2000);
//        } catch (InterruptedException e) {
//            Thread.currentThread().interrupt();
//            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "操作被中断");
//        }

//        dataMatchOrderItemMapper.getItemListByUid(uid).stream()
//                //.filter(item -> isWithin30Minutes(item, currentTime))
//                .forEach(item -> {
//                    MerchantBaseInfo merchant = merchantBaseInfoMapper.selectById(item.getInfoId());
//                    if (!(merchant.getSinglePushFlag() == 1 && item.getClickPushFlag() == 1)) {
//                        merchantAbiBDataPushInfoVO.add(buildPushInfoVO(item, merchant, memberSourceInfo));
//                    }
//                });
        String dateInfo = LocalDate.now().toString();
        List<DataMatchOrderItem> itemListByUid = dataMatchOrderItemMapper.getItemListByUid1(uid,dateInfo);

        //收集单推订单
        List<DataMatchOrderItem> singlePushZeroItems = itemListByUid.stream()
                .filter(item -> {
                    MerchantBaseInfo merchant = merchantBaseInfoMapper.selectById(item.getInfoId());
                    return merchant != null && merchant.getSinglePushFlag() == 0;
                })
                .collect(Collectors.toList());

        List<DataMatchOrderItem> orderItemList = itemListByUid.stream()
                .filter(item -> {
                    MerchantBaseInfo merchant = merchantBaseInfoMapper.selectById(item.getInfoId());
                    return merchant != null && merchant.getSinglePushFlag() == 1;
                })
                .collect(Collectors.toList());

        // 先按profitAmount降序排序，方便后续处理最高利润项
        singlePushZeroItems.sort(Comparator.comparing(DataMatchOrderItem::getProfitAmount).reversed());
        for (DataMatchOrderItem item : singlePushZeroItems) {
            MerchantBaseInfo merchant = merchantBaseInfoMapper.selectById(item.getInfoId());
            if(item.getClickPushFlag() == 1){
                jsonObject.put("dataList", resultList);
                return new ResponseVo(AppRspCodeConstant.SUCCESS, jsonObject);
            }
            if (merchant.getSinglePushFlag() == 0 && item.getClickPushFlag() == 0) {
                // 由于已经排序，第一个满足条件的项就是profitAmount最高的
                if (resultList.isEmpty()) {
                    MerchantAbiBDataPushInfoVO vo = buildPushInfoVO(item, merchant, memberSourceInfo, currentTime);
                    if (vo == null ) {
                        jsonObject.put("dataList",  resultList);
                        return new ResponseVo(AppRspCodeConstant.SUCCESS, "查询成功", jsonObject);
                    }
                    resultList.add(vo);
                    jsonObject.put("dataList", resultList.isEmpty() ? Collections.emptyList() : resultList);
                    return new ResponseVo(AppRspCodeConstant.SUCCESS, jsonObject);
                }
            }
        }

        for (DataMatchOrderItem item : orderItemList) {
            MerchantBaseInfo merchant = merchantBaseInfoMapper.selectById(item.getInfoId());
            if (merchant.getSinglePushFlag() == 1 && item.getClickPushFlag() == 0) {
                MerchantAbiBDataPushInfoVO vo = buildPushInfoVO(item, merchant, memberSourceInfo, currentTime);
                if (vo == null ) {
                    jsonObject.put("dataList",  resultList);
                    return new ResponseVo(AppRspCodeConstant.SUCCESS, "查询成功", jsonObject);
                }
                //if(vo.getInfoId().equals("297") || vo.getInfoId().equals("290")){
                    resultList.add(vo);
                //}
            }
        }

        jsonObject.put("dataList", resultList);
        return new ResponseVo(AppRspCodeConstant.SUCCESS, jsonObject);
    }


    private MerchantAbiBDataPushInfoVO buildPushInfoVO(DataMatchOrderItem item,
                                                       MerchantBaseInfo merchantBaseInfo,
                                                       MemberSourceInfo memberSourceInfo,
                                                       LocalDateTime currentTime) {
        Duration duration = Duration.between(item.getTimeoutPeriod(), currentTime);
        MerchantAbiBDataPushInfoVO merchantAbiBDataPushInfoVO = new MerchantAbiBDataPushInfoVO();
        if (Math.abs(duration.toMinutes()) <= 30) {
            merchantAbiBDataPushInfoVO.setApproveUrl(item.getApproveUrl());
            merchantAbiBDataPushInfoVO.setOrderItemId(String.valueOf(item.getId()));
            merchantAbiBDataPushInfoVO.setOrderId(String.valueOf(item.getOrderId()));
            merchantAbiBDataPushInfoVO.setInfoId(String.valueOf(merchantBaseInfo.getId()));
            merchantAbiBDataPushInfoVO.setCompanyName(merchantBaseInfo.getCompanyName());
            merchantAbiBDataPushInfoVO.setCompanyTitle(merchantBaseInfo.getCompanyTitle());
            merchantAbiBDataPushInfoVO.setCompanySubTitle(merchantBaseInfo.getCompanySubTitle());
            merchantAbiBDataPushInfoVO.setCompanyLogo(merchantBaseInfo.getCompanyLogo());
            merchantAbiBDataPushInfoVO.setMaxLoanAmount(merchantBaseInfo.getMaxLoanAmount());
            merchantAbiBDataPushInfoVO.setMaxRate(merchantBaseInfo.getMaxRate());
            merchantAbiBDataPushInfoVO.setMinRate(merchantBaseInfo.getMinRate() + "%");
            merchantAbiBDataPushInfoVO.setSpeed(merchantBaseInfo.getSpeed());
            merchantAbiBDataPushInfoVO.setLoanTime(merchantBaseInfo.getLoanTime());
            merchantAbiBDataPushInfoVO.setSublabelInfo(merchantBaseInfo.getSublabelInfo());
            merchantAbiBDataPushInfoVO.setStatus(true);

            // 特殊协议URL处理
            ApplicationInfo appInfo = applicationInfoService.getAppInfoByAppCode(memberSourceInfo.getAppCode());
            String infoIdStr = String.valueOf(item.getInfoId());
            switch (infoIdStr) {
                case "277":
                    merchantAbiBDataPushInfoVO.setHtmlContent(StrUtil.format("{}/page/damaiprotocol/{}.html",
                            appInfo.getApiUrl(), item.getUid()));
                    break;
                case "297":
                    merchantAbiBDataPushInfoVO.setHtmlContent(StrUtil.format("{}/page/protocoNewlWei/{}.html",
                            appInfo.getApiUrl(), item.getUid()));
                    break;
                case "307":
                    merchantAbiBDataPushInfoVO.setHtmlContent(StrUtil.format("{}/page/protocolHaoYong/{}.html",
                            appInfo.getApiUrl(), item.getUid()));
                    break;
                default:
                    merchantAbiBDataPushInfoVO.setHtmlContent(StrUtil.format("{}/page/newprotocolApib/{}/{}.html",
                            appInfo.getApiUrl(), item.getOrderId(), item.getId()));
            }
        }else {
            return null;
        }
        return merchantAbiBDataPushInfoVO;
    }
}

